package com.sh.data.engine.application.service.datadev;

import cn.hutool.core.convert.Convert;
import com.google.common.collect.Lists;
import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.datadev.*;
import com.sh.data.engine.application.model.dto.workspace.UserResponse;
import com.sh.data.engine.application.model.mapper.datadev.OfflineDevOperationJobResponsePageMapper;
import com.sh.data.engine.application.model.mapper.datadev.OfflineDevTaskManageResponsePageMapper;
import com.sh.data.engine.application.model.mapper.datadev.OfflineDevTaskMonitorErrorTaskResponsePageMapper;
import com.sh.data.engine.application.model.request.datadev.OfflineDevOperationJobSearchRequest;
import com.sh.data.engine.application.model.request.datadev.OfflineDevTaskManagerSearchRequest;
import com.sh.data.engine.common.util.ServletUtils;
import com.sh.data.engine.domain.base.model.PageResult;
import com.sh.data.engine.domain.base.model.UserContext;
import com.sh.data.engine.domain.datadev.offline.model.domain.*;
import com.sh.data.engine.domain.datadev.offline.model.param.OfflineDevOperationJobSearchParam;
import com.sh.data.engine.domain.datadev.offline.model.param.OfflineDevTaskManagerSearchParam;
import com.sh.data.engine.domain.datadev.offline.service.DatadevJobService;
import com.sh.data.engine.domain.datadev.offline.service.DatadevMenuNodeService;
import com.sh.data.engine.domain.util.ConvertUtil;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserDomain;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: mengzheng.mhc
 * @date: 2024/7/12 15:24
 */
@Slf4j
@Service
public class OfflineDevOperationV2ApplicationService {

    @Autowired
    private DatadevJobService datadevJobService;

    @Autowired
    private DatadevMenuNodeService datadevMenuNodeService;

    @Autowired
    private OfflineDevTaskMonitorErrorTaskResponsePageMapper offlineDevTaskMonitorErrorTaskResponsePageMapper;

    @Autowired
    private OfflineDevTaskManageResponsePageMapper offlineDevTaskManageResponsePageMapper;

    @Autowired
    private OfflineDevOperationJobResponsePageMapper offlineDevOperationJobResponsePageMapper;

    public OfflineDevOpeartionSummaryResponse getOfflineDevSummary(Long nodeId, Integer execType) {
        Long projectId = ServletUtils.getProjectId();
        OfflineDevOperationSummaryDomain offlineDevOperationSummaryDomain =
            datadevJobService.getOfflineDevSummary(nodeId, projectId, execType);

        return ConvertUtil.copyProperties(
            offlineDevOperationSummaryDomain, OfflineDevOpeartionSummaryResponse.class);
    }

    public OfflineDevTodayFinishedResponse getTodayFinishedResponse() {
        Long projectId = ServletUtils.getProjectId();
        OfflineDevOperationTodayFinishedDomain offlineDevOperationTodayFinishedDomain =
            datadevJobService.getTodayFinished(projectId);
        return Convert.convert(
            OfflineDevTodayFinishedResponse.class, offlineDevOperationTodayFinishedDomain);
    }

    public List<OfflineDevFailedTopResponse> getFailedTaskTopResponse(Integer timeType) {
        Long projectId = ServletUtils.getProjectId();
        List<OfflineDevOperationFailedTopDomain> offlineDevOperationFailedTopDomain =
            datadevJobService.getFailedTaskTop(projectId, timeType);

        return Convert.toList(OfflineDevFailedTopResponse.class, offlineDevOperationFailedTopDomain);
    }

    public List<OfflineDevRunningTimeTopResponse> getRunningTimeTopResponse(Date runDate) {
        Long projectId = ServletUtils.getProjectId();
        List<OfflineDevOperationRunningTimeTopDomain> offlineDevFailedTopDomain =
            datadevJobService.getRunningTimeTop(projectId, runDate);

        return Convert.toList(OfflineDevRunningTimeTopResponse.class, offlineDevFailedTopDomain);
    }

    public OfflineDevTaskMonitorResponse getTaskMonitorListResponse() {
        Long projectId = ServletUtils.getProjectId();
        OfflineDevOperationTaskMonitorDomain taskMonitorErrorDomain =
            datadevJobService.getTaskMonitorError(projectId);
        return Convert.convert(OfflineDevTaskMonitorResponse.class, taskMonitorErrorDomain);
    }

    public PagerResponse<OfflineDevTaskMonitorErrorTaskResponse> getTaskMonitorErrorTaskResponse(
        Integer timeCase, Integer pageNum, Integer pageSize) {
        Long projectId = ServletUtils.getProjectId();
        PageResult<OfflineDevOperationTaskMonitorErrorTaskDomain> taskMonitorErrorDomains =
            datadevJobService.getTaskMonitorErrorTask(timeCase, projectId, pageNum, pageSize);
        return offlineDevTaskMonitorErrorTaskResponsePageMapper.toPageResponse(taskMonitorErrorDomains);
    }

    public PagerResponse<OfflineDevTaskManageResponse> getOfflineDevTaskManagePage(
        OfflineDevTaskManagerSearchRequest request) {
        OfflineDevTaskManagerSearchParam convert =
            Convert.convert(OfflineDevTaskManagerSearchParam.class, request);
        PageResult<OfflineDevOperationTaskManageDomain> offlineDevTaskManageDomain =
            datadevMenuNodeService.getOfflineDevTaskManageList(convert);
        return offlineDevTaskManageResponsePageMapper.toPageResponse(offlineDevTaskManageDomain);
    }

    public List<OfflineDevTaskManageResponse> getOfflineDevTaskManageChildren(Long nodeId, Integer nodeType) {
        Long projectId = ServletUtils.getProjectId();
        List<OfflineDevOperationTaskManageDomain> res =
            datadevMenuNodeService.getOfflineDevTaskManageChildren(nodeId, projectId, nodeType);

        return Convert.toList(OfflineDevTaskManageResponse.class, res);
    }

    public List<OfflineDevOperationJobResponse> getOfflineDevOperationJobList(Long jobId, Integer nodeType) {
        List<OfflineDevOperationJobDomain> res = datadevJobService.getOfflineDevOperationJobList(jobId, nodeType);
        return ConvertUtil.copyProperties(res, OfflineDevOperationJobResponse.class);
    }

    public boolean saveTaskflowsStatus(Integer isLocked, String nodeIds) {
        Long projectId = ServletUtils.getProjectId();
        List<Long> flowIds = Lists.newArrayList();
        if (StringUtils.isNoneBlank(nodeIds)) {
            flowIds =
                Arrays.stream(nodeIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        }
        return datadevMenuNodeService.setTaskFlowScheduleStatus(flowIds, isLocked, projectId);
    }

    public boolean ignoreDataDevJob(String ids) {
        return datadevJobService.ignoreDataDevJob(ids);
    }

    public PagerResponse<OfflineDevOperationJobResponse> getOfflineDevOperationJobPage(
        OfflineDevOperationJobSearchRequest searchRequest) {
        Long projectId = ServletUtils.getProjectId();
        OfflineDevOperationJobSearchParam offlineDevOperationJobSearchParam =
            ConvertUtil.copyProperties(searchRequest, OfflineDevOperationJobSearchParam.class);
        offlineDevOperationJobSearchParam.setProjectId(projectId);
        PageResult<OfflineDevOperationJobDomain> offlineDevOperationJobPage = datadevJobService
            .getOfflineDevOperationJobPage(offlineDevOperationJobSearchParam);
        return offlineDevOperationJobResponsePageMapper.toPageResponse(offlineDevOperationJobPage);
    }

    public List<UserResponse> getUserList() {
        Long projectId = ServletUtils.getProjectId();
        List<UserDomain> all = datadevMenuNodeService.getUserList(projectId);
        return Convert.toList(UserResponse.class, all);
    }

    public OfflineDevTaskLogResponse taskLog(Long jobId, Integer offset, String rsHasShow) {
        OfflineDevTaskLogDomain taskLog = datadevJobService.getTaskLog(jobId, offset, rsHasShow);
        return ConvertUtil.copyProperties(taskLog, OfflineDevTaskLogResponse.class);
    }

    public Long taskRestart(Long id) {
        Long projectId = ServletUtils.getProjectId();
        String userId = UserContext.getUserId();
        Integer execType = 0;
        return datadevJobService.startTask(id, execType, projectId, userId);
    }

    public boolean taskStop(String logIds) {
        List<Long> ids =
            Arrays.stream(logIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        datadevJobService.stopAllFlowJob(ids);
        return true;
    }

    public Long flowTaskStart(Long nodeId) {
        Long projectId = ServletUtils.getProjectId();
        String userId = UserContext.getUserId();
        return datadevJobService.startTaskByNodeId(nodeId, projectId, userId, 0);
    }
}
